//! @Author: DengLibin 榆霖
//! @Date:  2022-06-30 14:10:11
//! @Description: web应用


use std::{
    cell::{Cell, RefCell},
    sync::{atomic::{AtomicUsize, Ordering}, Mutex, Arc},
};

use actix_files::Files;
use actix_session::CookieSession;
use actix_web::{
    http::{self},
    middleware::{self, ErrorHandlers},
    web::{Data},
    App, HttpServer,
};


use crate::{sys};
use crate::middleware::error_handle;
use crate::middleware::say_hi;
use crate::config;

static SESSION_SIGNING_KEY: &[u8] = &[0; 32];
/// @Author: DengLibin 榆霖
/// @Date:  2022-04-20 19:53:37
/// @Description: 开启web服务器
pub async fn run() -> std::io::Result<()> {
    sys::init::init();

    

     //全局计数器，非线程安全 使用锁
    let counter_mutex = Data::new(Mutex::new(0_usize));
    //全局计数器，使用原子操作
    let counter_atomic = Data::new(AtomicUsize::new(0_usize));
    //mysql连接池
    let mysql_conn_pool = Data::new(dao::mysql_conn_pool::create_conn_pool().unwrap());
    let async_mysql_conn_pool = Data::new(async_dao::mysql_conn_pool::get_conn_pool());

    //原子计数
    let arc_counter = Arc::new(AtomicUsize::new(0_usize));
    
    info!("arc_counter强引用计数:{}", Arc::strong_count(&arc_counter));

    info!("创建HttpServer");
    let http_server = HttpServer::new(move || {
        // Create some thread-local state
        // 线程本地状态（放到闭包内部，线程安全，设置了多少个工作线程，就有多个）
        let counter_cell = Cell::new(0u32);

        info!("arc_counter强引用计数:{}", Arc::strong_count(&arc_counter));
        //原子计数
        arc_counter.fetch_add(1, Ordering::SeqCst);
        let node_id = arc_counter.load(Ordering::SeqCst);
        info!("node_id:{}", node_id);
        let id_generator = common::utils::IdGenerator::new(1, node_id as i32);
        //RefCell内部可变
        let id_generator = Data::new(RefCell::new(id_generator));

        //错误捕捉
        let error_handlers = ErrorHandlers::new()
            .handler(
                http::StatusCode::INTERNAL_SERVER_ERROR,
                error_handle::internal_server_error,
            )
            .handler(http::StatusCode::BAD_REQUEST, error_handle::bad_request)
            .handler(http::StatusCode::NOT_FOUND, error_handle::not_found);

        info!("创建App");
        let app = App::new()
            //跨域配置
            //.wrap(cors::cors())
            // 压缩response 通常放到第一个
            .wrap(middleware::Compress::default())
            //CookieSession中间件 
            .wrap(CookieSession::signed(SESSION_SIGNING_KEY).secure(false))
            // enable logger 通常放到最后
            .wrap(middleware::Logger::default())
            //错误捕捉中间件
            .wrap(error_handlers)
            //自定义中间件
            .wrap(say_hi::SayHi)
            //.wrap(check_login::CheckLogin)
            
            //设置全局数据
            .app_data(counter_atomic.clone()) // add shared state
            .app_data(counter_mutex.clone()) // add shared state
            .app_data(Data::new(counter_cell)) //
            .app_data(mysql_conn_pool.clone()) // 
            .app_data(async_mysql_conn_pool.clone()) // 
            .app_data(id_generator.clone()) // 
            
            //.service(web::resource("/index.html").to(|| async { "Hello world!" }))
            //静态资源路径
            .service(Files::new("/static", "static").show_files_listing())

            //json，路由...配置
            .configure(config::web_config);
        
            
        return app;
    });
    info!("创建HttpServer完成");
    info!("绑定端口:{}启动,", 8080);
    http_server
        .bind(("127.0.0.1", 8080))?
        //.workers(2) //工作线程数 默认cpu数量
        .run()
        .await
}